﻿using Minecraft.Config;
using Minecraft.Model;
using Minecraft.Model.Backpack;
using Minecraft.Model.Furniture;
using Minecraft.Model.ReqResp;
using SuperSocket.SocketBase.Command;
using SuperSocket.SocketBase.Protocol;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Minecraft.ServerHall.Cmd
{
	/// <summary>
	/// 家具移除（产出家具，存储家具共用）
	/// </summary>
	public class FurnitureOutputRemove : CommandBase<MinecraftSession, StringRequestInfo>
	{
		public override string Name
		{
			get
			{
				return ProtocolHelper.GetProtocolStr(defCommand);
			}
		}
		private EnumCommand defCommand = EnumCommand.Furniture_FurnitureOutputRemove;
		public override void ExecuteCommand(MinecraftSession session, StringRequestInfo requestInfo)
		{
			var req = requestInfo.GetRequestObj<FurnitureOutputRemoveReq>(session);
			if (req == null)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误1：（原因：请求实体为空）" });
				return;
			}
			if (!session.minecraftSessionInfo.IsLogin)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误1：（原因：未登录）" });
				return;
			}


			//if (!MinecraftConfig.canRemoveFurnitureTypeList.Any(m => m == req.enumFurnitureType))
			//{
			//	session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：暂不支持该家具类型的移除【{req.enumFurnitureType.ToString()}】）" });
			//	return;
			//}

			if (req.furnitureId.IsNullOrWhiteSpace())
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：furnitureId 参数为空）" });
				return;
			}

			var furniture = session.GetAllFurnitureConvergeList().FirstOrDefault(m => m.FurnitureId == req.furnitureId);
			if (furniture == null)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：id为【{req.furnitureId}】的家具不存在）" });
				return;
			}

			var mod_FurnitureInfo = furniture.GetMod_FurnitureInfo();

			var timeNow = DateTimeOffset.Now;
			var map = session.minecraftSessionInfo.map;
			if (map.isMoving_Convert)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误1：（原因：正处于大地图界面的移动状态，不能调用此接口）" });
				return;
			}

			List<FurnitureOutputRemoveRespInfo> furnitureOutputRemoveRespInfoList = new List<FurnitureOutputRemoveRespInfo>();
			furnitureOutputRemoveRespInfoList.Add(new FurnitureOutputRemoveRespInfo
			{
				goodsItemId = furniture.FurnitureItemId,
				num = 1
			});
			List<BackpackCellInfo> dismantleFurnitureOutputGoodsList = new List<BackpackCellInfo>();
			int DropId = 0;
			switch (furniture.enumFurnitureType)
			{
				case EnumFurnitureType.Output:
					{
						if (furniture.Hp <= 0)
						{
							session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误8：（原因：家具 Hp <= 0）" });
							return;
						}

						//正在产出状态或者暂停状态，不允许操作
						var baseResp = furniture.GetFurnitureOutputInfo(session, out FurnitureOutputInfo furnitureOutputInfo);
						if (baseResp.RespLevel != RespLevelEnum.Success)
						{
							session.Send(defCommand, req, baseResp);
							return;
						}
						if (furnitureOutputInfo.enumFurnitureOutputState != EnumFurnitureOutputState.NotStart)
						{
							session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误3：（原因：正在产出中或者产出暂停中【{furnitureOutputInfo.enumFurnitureOutputState.ToString()}】，不允许操作）" });
							return;
						}
						//正在升级状态，不允许操作
						FurnitureOutputUpgradeInfo furnitureOutputUpgradeInfo = furniture.GetFurnitureOutputUpgradeInfo(session);
						if (furniture.Upgrade_State_Convert)
						{
							session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误3：（原因：正在升级中，不允许操作）" });
							return;
						}
						//正在修理状态，不允许操作
						FurnitureOutputRepairInfo furnitureOutputRepairInfo = furniture.GetFurnitureOutputRepairInfo(session);
						if (furnitureOutputRepairInfo.enumFurnitureOutputRepairState == EnumFurnitureOutputRepairState.Progressing)
						{
							session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误3：（原因：正在修理状态，不允许操作）" });
							return;
						}

						//产出栏中的相关物品
						furnitureOutputRemoveRespInfoList.AddRange(
							furniture.GetFurnitureOutputMaterialGoodsInfoList_Convert().Select(m => new FurnitureOutputRemoveRespInfo()
							{
								goodsItemId = m.GoodsItemId,
								num = m.Num
							}).ToList());
						if (furniture.Output_ResultGoodsNum > 0)
						{
							furnitureOutputRemoveRespInfoList.Add(new FurnitureOutputRemoveRespInfo
							{
								goodsItemId = furniture.Output_ResultGoodsItemId,
								num = furniture.Output_ResultGoodsNum
							});
						}
						//升级栏中的相关物品
						furnitureOutputRemoveRespInfoList.AddRange(
							furniture.GetFurnitureOutputUpgradeMaterialGoodsInfoList_Convert().Select(m => new FurnitureOutputRemoveRespInfo()
							{
								goodsItemId = m.GoodsItemId,
								num = m.Num
							}).ToList());
						//修理栏中的相关物品
						furnitureOutputRemoveRespInfoList.AddRange(
							furniture.GetFurnitureOutputRepairMaterialGoodsInfoList_Convert().Select(m => new FurnitureOutputRemoveRespInfo()
							{
								goodsItemId = m.GoodsItemId,
								num = m.Num
							}).ToList());
						//将移除的物品记录下来
						var dropinfo = new DropinfoModel
						{
							DropGoodsFrom = (int)EnumGoodsBelongsToType.MonsterCorpseAndDismantleFurniture,
							DropId = session.GetNewDropInfoId(),
							DropTime = timeNow,
							MapId = map.SourceMapId,
							PlayerId = session.minecraftSessionInfo.player.PlayerId,
						};
						session.minecraftSessionInfo.dropinfoList.Add(dropinfo);
						DropId = dropinfo.DropId;
						//对 furnitureOutputRemoveRespInfoList 重新整理，并放入goodslist中
						List<FurnitureOutputRemoveRespInfo> newFurnitureOutputRemoveRespInfoList = new List<FurnitureOutputRemoveRespInfo>();
						ArrangeGoods(session, furnitureOutputRemoveRespInfoList.DeepCopy(), newFurnitureOutputRemoveRespInfoList);
						var newGoodsList = new List<GoodsModel>();
						int position = 0;
						foreach (var newFurnitureOutputRemoveRespInfo in newFurnitureOutputRemoveRespInfoList)
						{
							newGoodsList.Add(new GoodsModel
							{
								BelongsTo = (int)EnumGoodsBelongsToType.MonsterCorpseAndDismantleFurniture,
								GoodsId = StringHelper.GetGuidStr(),
								GoodsItemId = newFurnitureOutputRemoveRespInfo.goodsItemId,
								GoodsPosition = position,
								guid = dropinfo.DropId.ToString(),
								Num = newFurnitureOutputRemoveRespInfo.num,
								WastageValue = 100,
								PlayerId = session.minecraftSessionInfo.player.PlayerId,
							});
							position++;
						}
						session.minecraftSessionInfo.goodsList.AddRange(newGoodsList);
						dismantleFurnitureOutputGoodsList = newGoodsList.GetBackpackGoodsCellInfo();
						session.minecraftSessionInfo.furnitureOutputList.RemoveAll(m => m.FurnitureId == req.furnitureId);
					}
					break;
				case EnumFurnitureType.Storage:
					{
						if (furniture.Hp <= 0)
						{
							session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误8：（原因：家具 Hp <= 0）" });
							return;
						}
						//存储家具中的所有物品
						var goodsList = session.minecraftSessionInfo.goodsList.Where(m => m.enumGoodsBelongsToType_Convert == EnumGoodsBelongsToType.FurnitureStorage && m.guid == furniture.FurnitureId).DeepCopy();
						furnitureOutputRemoveRespInfoList =
							(from info in goodsList.GetBackpackGoodsCellInfo()
							 select new FurnitureOutputRemoveRespInfo()
							 {
								 goodsItemId = info.GoodsItemId,
								 num = info.Num
							 }).ToList();
						foreach (var item in goodsList)
						{
							session.minecraftSessionInfo.goodsList.RemoveAll(m => m.GoodsId == item.GoodsId);
						}
						session.minecraftSessionInfo.furnitureStorageList.RemoveAll(m => m.FurnitureId == req.furnitureId);
					}
					break;
				case EnumFurnitureType.Treasurebox:
					{
						session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：暂未支持该类型家具类型的移除操作【{furniture.enumFurnitureType.ToString()}】）" });
						return;
					}
					break;
				default:
					{
						session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：判断错误【{furniture.enumFurnitureType.ToString()}】）" });
						return;
					}
					break;
			}

			var resp = new FurnitureOutputRemoveResp
			{
				DropId = DropId,
				furnitureId = furniture.FurnitureId,
				itemId = mod_FurnitureInfo.Id,
				point3 = furniture.point3,
				enumFurnitureType = furniture.enumFurnitureType,
				dismantleFurnitureOutputGoodsList = dismantleFurnitureOutputGoodsList
			};
			session.Send(defCommand, req, resp);
		}
		/// <summary>
		/// 整理
		/// </summary>
		/// <param name="oldFurnitureOutputRemoveRespInfoList"></param>
		/// <param name="newFurnitureOutputRemoveRespInfoList"></param>
		private void ArrangeGoods(MinecraftSession session, List<FurnitureOutputRemoveRespInfo> oldFurnitureOutputRemoveRespInfoList, List<FurnitureOutputRemoveRespInfo> newFurnitureOutputRemoveRespInfoList)
		{
			var oldInfo = oldFurnitureOutputRemoveRespInfoList.FirstOrDefault(m => m.num > 0);
			if (oldInfo != null)
			{
				int canMoveCount = 0;
				var maxCount = session.GetMaxCellNumConvert(oldInfo.goodsItemId);
				var newInfo = newFurnitureOutputRemoveRespInfoList.FirstOrDefault(m => m.goodsItemId == oldInfo.goodsItemId && m.num < maxCount);
				if (newInfo != null)
				{
					canMoveCount = Math.Min(oldInfo.num, maxCount) - newInfo.num;
					newInfo.num += canMoveCount;
				}
				else
				{
					canMoveCount = Math.Min(oldInfo.num, maxCount);
					newFurnitureOutputRemoveRespInfoList.Add(new FurnitureOutputRemoveRespInfo
					{
						goodsItemId = oldInfo.goodsItemId,
						num = canMoveCount
					});
				}
				oldInfo.num -= canMoveCount;
				ArrangeGoods(session, oldFurnitureOutputRemoveRespInfoList, newFurnitureOutputRemoveRespInfoList);
			}
			else
			{

			}
		}
	}
}
